/* Copyright (c) 2007-2012, ben "boin" bonoeil */

#ifndef _HL2DEMO_DEFS_H_
#define _HL2DEMO_DEFS_H_

#include <stdint.h>
#include <sys/types.h>

#define HL2DEMO_MAGIC "HL2DEMO"
#define DEM_PROTOCOL  3
#define NET_PROTOCOL  7 /* 15 for OB */

/** Demo File header. */
struct hl2demo_fheader_s {
  int8_t magic[8];         /**< Should be dem_magic "HL2DEMO"  */
  int8_t dem_ver[4];       /**< Should be DEMO_PROTOCOL (3)    */
  int8_t net_ver[4];       /**< Should be  PROTOCOL_VERSION    */
  int8_t sv_name[260];     /**< Server name (the game was played in). */
  int8_t tv_name[260];     /**< Client name (recorder).               */
  int8_t mp_name[260];     /**< Map name.                             */
  int8_t gm_name[260];     /**< game directory (com_gamedir).         */
  int8_t pb_time[4];       /**< Time of track                  */
  int8_t pb_tick[4];       /**< # of ticks in track            */
  int8_t pb_fram[4];       /**< # of frames in track           */
  int8_t sig_len[4];       /**< length of sigondata in bytes   */
};

/** Demo decoded header. */
struct hl2demo_header_s {
  char  magic[8];        /**< Should be dem_magic "HL2DEMO"  */
  int   dem_ver;         /**< Should be DEMO_PROTOCOL (3)    */
  int   net_ver;         /**< Should be PROTOCOL_VERSION (7:old 15:OB) */

  char  sv_name[260];    /**< Server name (the game was played in). */
  char  tv_name[260];    /**< Client name (recorder).               */
  char  mp_name[260];    /**< Map name.                             */
  char  gm_name[260];    /**< game directory (com_gamedir).         */

  float pb_time;         /**< Time of track                  */
  int   pb_tick;         /**< # of ticks in track            */
  int   pb_fram;         /**< # of frames in track           */
  int   sig_len;         /**< length of sigondata in bytes   */

};

typedef struct hl2demo_header_s hl2demo_header_t;

#define FDEMO_NORMAL      0
#define FDEMO_USE_ORIGIN2 (1<<0)
#define FDEMO_USE_ANGLES2 (1<<1)
#define FDEMO_NOINTERP    (1<<2) /* don't interp betw this and last view */


struct hl2demo_vector_s {
  float x, y, z;
};
typedef struct hl2demo_vector_s hl2demo_vector_t;
typedef hl2demo_vector_t hl2demo_qangle_t;
typedef int32_t bool;

/** Demo messages */
enum {
  dem_signon = 1,   /**< startup message, process as fast as possible. */
  dem_packet,       /**< normal network packet that we stored off.     */
  dem_synctick,     /**< sync client clock to demo tick.               */
  dem_consolecmd,   /**< console command.                              */
  dem_usercmd,      /**< user input command.                           */
  dem_datatables,   /**< network data tables.                          */
  dem_stop,         /**< end of time.                                  */
  dem_stringtables, /**< dem_stringtable.                              */

  dem_lastcmd       /**< Last command */
};

struct hl2demo_cmdinfo_s {
  int32_t flags;

  /* original origin/viewangles */
  hl2demo_vector_t vo1;  /* view origin */
  hl2demo_qangle_t va1;  /* view angles; */
  hl2demo_qangle_t lva1; /* local view angles */

  /* resampled origin/viewangles */
  hl2demo_vector_t vo2;  /* view origin */
  hl2demo_qangle_t va2;  /* view angles; */
  hl2demo_qangle_t lva2; /* local view angles */
};
typedef struct hl2demo_cmdinfo_s hl2demo_cmdinfo_t;

typedef struct hl2demo_message_s hl2demo_message_t;
struct hl2demo_message_s {
  hl2demo_message_t * nxt;      /**< Next message.         */
  int cnt;                      /**< Message ID.           */
  int tck;                      /**< Tick number.          */
  int cmd;                      /**< Message command.      */

  hl2demo_cmdinfo_t cmdinfo;    /**< Command Info.         */

  int seq_in;                   /**< Sequence Input ID.    */
  int seq_out;                  /**< Sequence Output ID.   */

  size_t pos;                   /**< Position in file.     */
  char * buf;                   /**< Data buffer.          */
  size_t len;                   /**< Length of data block. */
};

struct hl2demo_s {
  hl2demo_header_t   header;
  hl2demo_message_t  * msghead, * msgtail;
};
typedef struct hl2demo_s hl2demo_t;

#endif /* #ifndef _HL2DEMO_DEFS_H_ */
